<script setup>
import { ref, computed, onMounted, nextTick } from 'vue';
import CodeBlock from '@components/CodeBlock.vue';

// 选项卡控制
const activeTab = ref('basic');
const tabs = [
  { id: 'basic', name: '基础过渡' },
  { id: 'list', name: '列表过渡' },
  { id: 'css', name: 'CSS动画' },
  { id: 'js', name: 'JS动画' }
];

// 代码示例常量定义
const fadeTransitionExampleCode = `<transition name="fade">
  <div v-if="show">
    淡入淡出动画示例
  </div>
</transition>`;

const listTransitionExampleCode = `<transition-group name="list" tag="ul">
  <li v-for="item in items" :key="item.id">
    {{ item.text }}
  </li>
</transition-group>`;

const customClassTransitionExampleCode = `<transition
  name="slide-fade"
  enter-active-class="animate__animated animate__slideInLeft"
  leave-active-class="animate__animated animate__slideOutRight"
  appear
>
  <div v-if="show">
    自定义CSS类的过渡动画
  </div>
</transition>`;

const staggeredTransitionCode = `<transition-group
  name="staggered"
  tag="div"
  class="staggered-list"
  v-bind:css="false"
  @before-enter="beforeEnter"
  @enter="enter"
  @leave="leave"
>
  <div
    v-for="(item, index) in items"
    :key="item"
    :data-index="index"
  >
    {{ item }}
  </div>
</transition-group>`;

const dynamicTransitionCode = `<transition
  :name="transitionName"
  :duration="transitionDuration"
>
  <div v-if="show" class="box">
    动态过渡效果
  </div>
</transition>`;

// 基础过渡演示
const isVisible = ref(false);
const toggleVisibility = () => {
  isVisible.value = !isVisible.value;
};

// 动态过渡效果
const transitionName = ref('fade');
const transitionDuration = ref(300);
const transitionOptions = ['fade', 'slide', 'bounce', 'scale', 'flip'];
const durationOptions = [150, 300, 500, 800, 1000];

const changeTransition = () => {
  const currentIndex = transitionOptions.indexOf(transitionName.value);
  const nextIndex = (currentIndex + 1) % transitionOptions.length;
  transitionName.value = transitionOptions[nextIndex];
};

const changeDuration = () => {
  const currentIndex = durationOptions.indexOf(transitionDuration.value);
  const nextIndex = (currentIndex + 1) % durationOptions.length;
  transitionDuration.value = durationOptions[nextIndex];
};

// 列表动画演示数据
const listItems = ref(['项目 1', '项目 2', '项目 3']);
const newItem = ref('');

const addItem = () => {
  if (newItem.value.trim()) {
    listItems.value.push(newItem.value.trim());
    newItem.value = '';
  }
};

const removeItem = (index) => {
  listItems.value.splice(index, 1);
};

const clearList = () => {
  listItems.value = [];
};

const resetList = () => {
  listItems.value = ['项目 1', '项目 2', '项目 3'];
};

// 交错动画数据和方法
const staggeredItems = ref([
  { id: 1, text: '交错动画项 1' },
  { id: 2, text: '交错动画项 2' },
  { id: 3, text: '交错动画项 3' },
  { id: 4, text: '交错动画项 4' },
  { id: 5, text: '交错动画项 5' }
]);
const newStaggeredItem = ref('');
let nextId = 6;

const addStaggeredItem = () => {
  if (newStaggeredItem.value.trim()) {
    staggeredItems.value.push({
      id: nextId++,
      text: newStaggeredItem.value.trim()
    });
    newStaggeredItem.value = '';
  }
};

const removeStaggeredItem = (id) => {
  const index = staggeredItems.value.findIndex(item => item.id === id);
  if (index !== -1) {
    staggeredItems.value.splice(index, 1);
  }
};

// JavaScript动画钩子
const beforeEnter = (el) => {
  el.style.opacity = 0;
  el.style.transform = 'translateY(30px)';
};

const enter = (el, done) => {
  const delay = el.dataset.index * 150;
  setTimeout(() => {
    el.style.transition = 'opacity 0.3s ease, transform 0.3s ease';
    el.style.opacity = 1;
    el.style.transform = 'translateY(0)';
    el.addEventListener('transitionend', done);
  }, delay);
};

const leave = (el, done) => {
  const delay = el.dataset.index * 150;
  setTimeout(() => {
    el.style.opacity = 0;
    el.style.transform = 'translateY(-30px)';
    el.addEventListener('transitionend', done);
  }, delay);
};

// 数字动画
const counter = ref(0);
const increaseCounter = () => {
  counter.value++;
};

const decreaseCounter = () => {
  if (counter.value > 0) {
    counter.value--;
  }
};

// 页面切换动画演示
const currentPage = ref(1);
const totalPages = 3;

const nextPage = () => {
  currentPage.value = currentPage.value < totalPages ? currentPage.value + 1 : 1;
};

const prevPage = () => {
  currentPage.value = currentPage.value > 1 ? currentPage.value - 1 : totalPages;
};

// 入场动画控制
const showAppear = ref(false);
onMounted(() => {
  nextTick(() => {
    showAppear.value = true;
  });
});

// 颜色渐变动画
const colorIndex = ref(0);
const colors = ['#667eea', '#764ba2', '#f093fb', '#f5576c', '#4facfe'];

const changeColor = () => {
  colorIndex.value = (colorIndex.value + 1) % colors.length;
};

const currentColor = computed(() => colors[colorIndex.value]);

// 3D变换动画
const rotateY = ref(0);
const rotateZ = ref(0);

const resetRotation = () => {
  rotateY.value = 0;
  rotateZ.value = 0;
};

const rotate3D = () => {
  rotateY.value = 360;
  rotateZ.value = 360;
};
</script>

<template>
  <div class="animation-transition-demo">
    <transition name="fade" appear>
      <h2 v-if="showAppear" class="demo-title">✨ Vue 3 动画与过渡效果高级演示</h2>
    </transition>
    
    <!-- 选项卡导航 -->
    <div class="tabs-container">
      <button 
        v-for="tab in tabs" 
        :key="tab.id"
        class="tab-button"
        :class="{ active: activeTab === tab.id }"
        @click="activeTab = tab.id"
      >
        {{ tab.name }}
      </button>
    </div>
    
    <!-- 选项卡内容 -->
    <div class="tab-content">
      <!-- 基础过渡选项卡 -->
      <div v-if="activeTab === 'basic'" class="tab-pane">
        <div class="demo-grid">
          <!-- 基本淡入淡出 -->
          <div class="demo-card">
            <h3 class="card-title">基础淡入淡出</h3>
            <div class="demo-content">
              <button class="control-btn" @click="toggleVisibility">
                {{ isVisible ? '隐藏元素' : '显示元素' }}
              </button>
              
              <transition name="fade" mode="out-in">
                <div v-if="isVisible" key="visible" class="transition-box">
                  这是一个带有淡入淡出效果的元素
                </div>
              </transition>
              
              <div class="code-snippet">
                <CodeBlock :code="fadeTransitionExampleCode" language="html"></CodeBlock>
              </div>
            </div>
          </div>
          
          <!-- 动态过渡效果 -->
          <div class="demo-card">
            <h3 class="card-title">动态过渡效果</h3>
            <div class="demo-content">
              <div class="control-group">
                <button class="control-btn" @click="toggleVisibility">
                  {{ isVisible ? '隐藏元素' : '显示元素' }}
                </button>
                <button class="control-btn" @click="changeTransition">
                  切换效果: {{ transitionName }}
                </button>
                <button class="control-btn" @click="changeDuration">
                  持续时间: {{ transitionDuration }}ms
                </button>
              </div>
              
              <transition :name="transitionName" :duration="transitionDuration" mode="out-in">
                <div v-if="isVisible" :key="transitionName" class="transition-box">
                  {{ transitionName === 'fade' ? '淡入淡出' : 
                     transitionName === 'slide' ? '滑入滑出' : 
                     transitionName === 'bounce' ? '弹跳效果' : 
                     transitionName === 'scale' ? '缩放效果' : '翻转效果' }}
                </div>
              </transition>
              
              <div class="code-snippet">
                <CodeBlock :code="dynamicTransitionCode" language="html"></CodeBlock>
              </div>
            </div>
          </div>
          
          <!-- 颜色渐变动画 -->
          <div class="demo-card">
            <h3 class="card-title">颜色渐变动画</h3>
            <div class="demo-content">
              <button class="control-btn" @click="changeColor">
                改变颜色
              </button>
              
              <div class="color-transition-box" :style="{ backgroundColor: currentColor }">
                颜色渐变动画示例
              </div>
            </div>
          </div>
          
          <!-- 3D变换动画 -->
          <div class="demo-card">
            <h3 class="card-title">3D变换动画</h3>
            <div class="demo-content">
              <div class="control-group">
                <button class="control-btn" @click="rotate3D">
                  3D旋转
                </button>
                <button class="control-btn" @click="resetRotation">
                  重置
                </button>
              </div>
              
              <div class="transform-3d-box" :style="{
                transform: `rotateY(${rotateY}deg) rotateZ(${rotateZ}deg)`
              }">
                3D变换演示
              </div>
            </div>
          </div>
        </div>
      </div>
      
      <!-- 列表过渡选项卡 -->
      <div v-if="activeTab === 'list'" class="tab-pane">
        <div class="demo-grid">
          <!-- 基础列表动画 -->
          <div class="demo-card">
            <h3 class="card-title">基础列表动画</h3>
            <div class="demo-content">
              <div class="list-controls">
                <input 
                  v-model="newItem" 
                  type="text" 
                  placeholder="输入新项目"
                  class="list-input"
                  @keyup.enter="addItem"
                />
                <button class="control-btn" @click="addItem">添加</button>
                <button class="control-btn danger" @click="clearList">清空</button>
                <button class="control-btn" @click="resetList">重置</button>
              </div>
              
              <transition-group name="list" tag="ul" class="animated-list">
                <li 
                  v-for="(item, index) in listItems" 
                  :key="item"
                  class="list-item"
                >
                  {{ item }}
                  <button class="remove-btn" @click="removeItem(index)">×</button>
                </li>
              </transition-group>
              
              <div class="code-snippet">
                <CodeBlock :code="listTransitionExampleCode" language="html"></CodeBlock>
              </div>
            </div>
          </div>
          
          <!-- 交错动画 -->
          <div class="demo-card">
            <h3 class="card-title">交错动画</h3>
            <div class="demo-content">
              <div class="list-controls">
                <input 
                  v-model="newStaggeredItem" 
                  type="text" 
                  placeholder="添加交错动画项"
                  class="list-input"
                  @keyup.enter="addStaggeredItem"
                />
                <button class="control-btn" @click="addStaggeredItem">添加</button>
              </div>
              
              <transition-group 
                name="staggered" 
                tag="div" 
                class="staggered-list"
                v-bind:css="false"
                @before-enter="beforeEnter"
                @enter="enter"
                @leave="leave"
              >
                <div 
                  v-for="(item, index) in staggeredItems" 
                  :key="item.id"
                  :data-index="index"
                  class="staggered-item"
                >
                  {{ item.text }}
                  <button class="remove-btn" @click="removeStaggeredItem(item.id)">×</button>
                </div>
              </transition-group>
              
              <div class="code-snippet">
                <CodeBlock :code="staggeredTransitionCode" language="html"></CodeBlock>
              </div>
            </div>
          </div>
        </div>
      </div>
      
      <!-- CSS动画选项卡 -->
      <div v-if="activeTab === 'css'" class="tab-pane">
        <div class="demo-grid">
          <!-- 数字动画 -->
          <div class="demo-card">
            <h3 class="card-title">数字动画</h3>
            <div class="demo-content">
              <div class="control-group">
                <button class="control-btn" @click="decreaseCounter">
                  减少计数
                </button>
                <button class="control-btn" @click="increaseCounter">
                  增加计数
                </button>
              </div>
              
              <div class="number-counter">
                <span class="animated-number">{{ counter }}</span>
              </div>
            </div>
          </div>
          
          <!-- 页面切换动画 -->
          <div class="demo-card">
            <h3 class="card-title">页面切换动画</h3>
            <div class="demo-content">
              <div class="page-controls">
                <button class="control-btn" @click="prevPage">上一页</button>
                <span class="page-indicator">页面 {{ currentPage }} / {{ totalPages }}</span>
                <button class="control-btn" @click="nextPage">下一页</button>
              </div>
              
              <transition name="page" mode="out-in">
                <div :key="currentPage" class="page-content">
                  <div v-if="currentPage === 1">
                    <h4>第一页内容</h4>
                    <p>这是第一个页面的示例内容，带有优雅的页面切换动画效果。</p>
                  </div>
                  <div v-else-if="currentPage === 2">
                    <h4>第二页内容</h4>
                    <p>这是第二个页面的示例内容，展示了Vue 3的过渡系统能力。</p>
                  </div>
                  <div v-else>
                    <h4>第三页内容</h4>
                    <p>这是第三个页面的示例内容，使用mode="out-in"确保动画平滑过渡。</p>
                  </div>
                </div>
              </transition>
            </div>
          </div>
        </div>
      </div>
      
      <!-- JS动画选项卡 -->
      <div v-if="activeTab === 'js'" class="tab-pane">
        <div class="demo-grid">
          <!-- 过渡钩子 -->
          <div class="demo-card">
            <h3 class="card-title">JavaScript动画钩子</h3>
            <div class="demo-content">
              <button class="control-btn" @click="toggleVisibility">
                触发JS动画
              </button>
              
              <transition 
                name="custom" 
                @before-enter="el => { console.log('动画开始前'); el.style.opacity = 0; }"
                @enter="el => { console.log('动画执行中'); setTimeout(() => { el.style.opacity = 1; }, 10); }"
                @after-enter="() => console.log('动画结束后')"
                @before-leave="el => { console.log('离开动画开始前'); }"
                @leave="el => { console.log('离开动画执行中'); el.style.opacity = 0; }"
                @after-leave="() => console.log('离开动画结束后')"
              >
                <div v-if="isVisible" class="hook-box">
                  打开控制台查看JS动画钩子日志
                </div>
              </transition>
              
              <div class="code-snippet">
                <CodeBlock :code="customClassTransitionExampleCode" language="html"></CodeBlock>
              </div>
            </div>
          </div>
        </div>
      </div>
    </div>
  </div>
</template>

<style scoped>
.animation-transition-demo {
  padding: 20px;
  max-width: 1200px;
  margin: 0 auto;
}

.demo-title {
  text-align: center;
  margin-bottom: 30px;
  font-size: 2.2rem;
  font-weight: 700;
  background: linear-gradient(135deg, #667eea 0%, #764ba2 100%);
  -webkit-background-clip: text;
  -webkit-text-fill-color: transparent;
  background-clip: text;
  animation: titleAppear 1s ease-out;
}

@keyframes titleAppear {
  from {
    opacity: 0;
    transform: translateY(-20px);
  }
  to {
    opacity: 1;
    transform: translateY(0);
  }
}

/* 选项卡样式 */
.tabs-container {
  display: flex;
  justify-content: center;
  gap: 10px;
  margin-bottom: 30px;
  flex-wrap: wrap;
}

.tab-button {
  padding: 12px 24px;
  background-color: #f0f0f0;
  border: none;
  border-radius: 25px;
  cursor: pointer;
  transition: all 0.3s ease;
  font-weight: 500;
  color: #666;
}

.tab-button:hover {
  background-color: #e0e0e0;
  transform: translateY(-2px);
}

.tab-button.active {
  background-color: #667eea;
  color: white;
  box-shadow: 0 4px 12px rgba(102, 126, 234, 0.3);
}

.tab-content {
  animation: fadeIn 0.5s ease;
}

.tab-pane {
  animation: slideIn 0.5s ease;
}

@keyframes fadeIn {
  from { opacity: 0; }
  to { opacity: 1; }
}

@keyframes slideIn {
  from {
    opacity: 0;
    transform: translateY(20px);
  }
  to {
    opacity: 1;
    transform: translateY(0);
  }
}

/* 演示网格布局 */
.demo-grid {
  display: grid;
  grid-template-columns: repeat(auto-fit, minmax(350px, 1fr));
  gap: 30px;
  margin-bottom: 40px;
}

.demo-card {
  background: white;
  border-radius: 16px;
  box-shadow: 0 8px 24px rgba(0, 0, 0, 0.1);
  padding: 25px;
  transition: transform 0.3s ease, box-shadow 0.3s ease;
  position: relative;
  overflow: hidden;
}

.demo-card::before {
  content: '';
  position: absolute;
  top: 0;
  left: 0;
  width: 100%;
  height: 4px;
  background: linear-gradient(90deg, #667eea, #764ba2);
}

.demo-card:hover {
  transform: translateY(-5px);
  box-shadow: 0 12px 30px rgba(0, 0, 0, 0.15);
}

.card-title {
  color: #667eea;
  margin-bottom: 20px;
  font-size: 1.4rem;
  font-weight: 600;
}

.demo-content {
  display: flex;
  flex-direction: column;
  gap: 20px;
}

/* 控制按钮样式 */
.control-btn {
  padding: 10px 20px;
  background-color: #667eea;
  color: white;
  border: none;
  border-radius: 8px;
  cursor: pointer;
  transition: all 0.3s ease;
  font-weight: 500;
  font-size: 14px;
}

.control-btn:hover {
  background-color: #764ba2;
  transform: translateY(-1px);
  box-shadow: 0 4px 12px rgba(102, 126, 234, 0.3);
}

.control-btn.danger {
  background-color: #ff6b6b;
}

.control-btn.danger:hover {
  background-color: #ff5252;
}

.control-group {
  display: flex;
  gap: 12px;
  flex-wrap: wrap;
}

/* 过渡动画效果 */
/* 基本淡入淡出动画 */
.fade-enter-active, .fade-leave-active {
  transition: opacity 0.5s ease;
}

.fade-enter-from, .fade-leave-to {
  opacity: 0;
}

/* 滑动动画 */
.slide-enter-active, .slide-leave-active {
  transition: transform 0.5s ease, opacity 0.5s ease;
}

.slide-enter-from {
  transform: translateX(-100%);
  opacity: 0;
}

.slide-leave-to {
  transform: translateX(100%);
  opacity: 0;
}

/* 弹跳动画 */
.bounce-enter-active {
  animation: bounce-in 0.5s;
}

.bounce-leave-active {
  animation: bounce-out 0.5s;
}

@keyframes bounce-in {
  0% { transform: scale(0); }
  50% { transform: scale(1.2); }
  100% { transform: scale(1); }
}

@keyframes bounce-out {
  0% { transform: scale(1); }
  50% { transform: scale(1.2); }
  100% { transform: scale(0); }
}

/* 缩放动画 */
.scale-enter-active, .scale-leave-active {
  transition: transform 0.5s ease, opacity 0.5s ease;
}

.scale-enter-from, .scale-leave-to {
  transform: scale(0);
  opacity: 0;
}

/* 翻转动画 */
.flip-enter-active, .flip-leave-active {
  transition: all 0.6s ease;
}

.flip-enter-from {
  opacity: 0;
  transform: perspective(400px) rotateY(-90deg);
}

.flip-leave-to {
  opacity: 0;
  transform: perspective(400px) rotateY(90deg);
}

/* 过渡元素样式 */
.transition-box {
  background-color: #667eea;
  color: white;
  padding: 25px;
  border-radius: 12px;
  text-align: center;
  font-size: 1.1rem;
  font-weight: 500;
  min-height: 100px;
  display: flex;
  align-items: center;
  justify-content: center;
}

/* 颜色渐变动画 */
.color-transition-box {
  color: white;
  padding: 25px;
  border-radius: 12px;
  text-align: center;
  font-size: 1.1rem;
  font-weight: 500;
  min-height: 100px;
  display: flex;
  align-items: center;
  justify-content: center;
  transition: background-color 0.8s ease;
}

/* 3D变换动画 */
.transform-3d-box {
  background-color: #667eea;
  color: white;
  padding: 25px;
  border-radius: 12px;
  text-align: center;
  font-size: 1.1rem;
  font-weight: 500;
  min-height: 100px;
  display: flex;
  align-items: center;
  justify-content: center;
  transition: transform 1s ease;
  transform-style: preserve-3d;
}

/* 列表动画 */
.list-controls {
  display: flex;
  gap: 12px;
  flex-wrap: wrap;
}

.list-input {
  flex: 1;
  min-width: 120px;
  padding: 10px 15px;
  border: 2px solid #e0e0e0;
  border-radius: 8px;
  transition: border-color 0.3s ease;
  font-size: 14px;
}

.list-input:focus {
  outline: none;
  border-color: #667eea;
}

.animated-list {
  list-style: none;
  padding: 0;
  margin: 0;
}

.list-item {
  background-color: #f8f9fa;
  padding: 15px;
  border-radius: 8px;
  margin-bottom: 10px;
  display: flex;
  justify-content: space-between;
  align-items: center;
  border: 1px solid #e0e0e0;
  transition: background-color 0.3s ease;
}

.list-item:hover {
  background-color: #f0f2f5;
}

.remove-btn {
  background-color: #ff6b6b;
  color: white;
  border: none;
  border-radius: 50%;
  width: 28px;
  height: 28px;
  cursor: pointer;
  display: flex;
  align-items: center;
  justify-content: center;
  font-size: 18px;
  line-height: 1;
  transition: all 0.3s ease;
}

.remove-btn:hover {
  background-color: #ff5252;
  transform: scale(1.1);
}

/* 列表动画 */
.list-enter-active, .list-leave-active {
  transition: all 0.5s ease;
}

.list-enter-from {
  opacity: 0;
  transform: translateX(-30px);
}

.list-leave-to {
  opacity: 0;
  transform: translateX(30px);
}

.list-move {
  transition: transform 0.5s ease;
}

/* 交错动画 */
.staggered-list {
  display: flex;
  flex-direction: column;
  gap: 10px;
}

.staggered-item {
  background-color: #f8f9fa;
  padding: 15px;
  border-radius: 8px;
  display: flex;
  justify-content: space-between;
  align-items: center;
  border: 1px solid #e0e0e0;
}

/* 数字动画 */
.number-counter {
  text-align: center;
  padding: 20px;
}

.animated-number {
  font-size: 4rem;
  font-weight: bold;
  color: #667eea;
  transition: all 0.3s ease;
  display: inline-block;
  text-shadow: 0 2px 4px rgba(0, 0, 0, 0.1);
}

.animated-number:hover {
  transform: scale(1.1);
  color: #764ba2;
}

/* 页面切换动画 */
.page-controls {
  display: flex;
  justify-content: space-between;
  align-items: center;
  margin-bottom: 20px;
}

.page-indicator {
  font-weight: bold;
  color: #666;
}

.page-content {
  background-color: #f8f9fa;
  padding: 30px;
  border-radius: 12px;
  min-height: 200px;
  border: 1px solid #e0e0e0;
}

.page-content h4 {
  color: #667eea;
  margin-bottom: 15px;
  font-size: 1.3rem;
}

.page-content p {
  color: #666;
  line-height: 1.6;
}

.page-enter-active, .page-leave-active {
  transition: all 0.5s ease;
}

.page-enter-from {
  transform: translateX(100%);
  opacity: 0;
}

.page-leave-to {
  transform: translateX(-100%);
  opacity: 0;
}

/* 自定义钩子动画 */
.hook-box {
  background-color: #764ba2;
  color: white;
  padding: 25px;
  border-radius: 12px;
  text-align: center;
  font-size: 1.1rem;
  font-weight: 500;
  min-height: 100px;
  display: flex;
  align-items: center;
  justify-content: center;
}

/* 代码片段样式 */
.code-snippet {
  background-color: #f8f9fa;
  border-radius: 8px;
  padding: 15px;
  overflow-x: auto;
  border: 1px solid #e0e0e0;
  margin-top: 15px;
}

.code-snippet pre {
  margin: 0;
  font-family: 'Monaco', 'Consolas', 'Courier New', monospace;
  font-size: 13px;
  color: #333;
  line-height: 1.5;
}

/* 响应式设计 */
@media (max-width: 1024px) {
  .demo-grid {
    grid-template-columns: 1fr 1fr;
  }
}

@media (max-width: 768px) {
  .animation-transition-demo {
    padding: 15px;
  }
  
  .demo-title {
    font-size: 1.8rem;
    margin-bottom: 20px;
  }
  
  .demo-grid {
    grid-template-columns: 1fr;
    gap: 20px;
  }
  
  .tabs-container {
    flex-direction: column;
    align-items: center;
  }
  
  .tab-button {
    width: 100%;
    max-width: 250px;
  }
  
  .control-group, .list-controls, .page-controls {
    flex-direction: column;
  }
  
  .control-btn {
    width: 100%;
  }
  
  .animated-number {
    font-size: 3rem;
  }
  
  .transition-box, .color-transition-box, .transform-3d-box, .hook-box {
    min-height: 80px;
    padding: 20px;
  }
}

@media (max-width: 480px) {
  .demo-title {
    font-size: 1.5rem;
  }
  
  .demo-card {
    padding: 20px;
  }
  
  .animated-number {
    font-size: 2.5rem;
  }
}
</style>